import {DataStore} from "./base/DataStore.js";
import {UpPencil} from "./runtime/UpPencil.js";
import {DownPencil} from "./runtime/DownPencil.js";


export class Director {
    static getInstance() {
        if (!Director.instance) {
            Director.instance = new Director();
        }
        return Director.instance;
    }

    constructor() {
        // console.log("Director()")
        this.datastore = DataStore.getInstance();
        this.speed = 2;
        this.distance = 0;
    }

    createPencil() {
        let top = this.getRandomTop();
        this.datastore.get('pencils').push(new UpPencil(top));
        this.datastore.get('pencils').push(new DownPencil(top));
    }

    getRandomTop() {
        const minTop = DataStore.getInstance().canvas.height / 8;
        const maxTop = DataStore.getInstance().canvas.height / 2;
        const top = minTop + Math.random() * (maxTop - minTop);
        return top;
    }

    queuePencil() {
        console.log("queuePencil()");
        const pencils = this.datastore.get('pencils');
        console.log("pencils len:"+pencils.length);

        if (pencils.length < 4 && this.distance >= DataStore.getInstance().canvas.width / 2) {
            this.createPencil();
        } else if (pencils[0].x + pencils[0].width <= 0 && pencils.length === 4) {
            console.log("queue");
            let up = pencils.shift();
            let down = pencils.shift();
            let top = this.getRandomTop();
            up.top = top;
            down.top = top;
            up.x = DataStore.getInstance().canvas.width;
            down.x = DataStore.getInstance().canvas.width;
            pencils.push(up);
            pencils.push(down);
        }
    }

    birdEvent() {
        let bird = this.datastore.get('bird');
        bird.y = bird.curY;
        this.datastore.get('bird').downtime = 0;
    }

    static isStrike(birdBorder, pencilBorder) {
        let s = false;

        if (birdBorder.right > pencilBorder.left && birdBorder.left < pencilBorder.right) {
            if ((pencilBorder.top < 0 && birdBorder.top < pencilBorder.bottom) || (pencilBorder.top > 0 && birdBorder.bottom > pencilBorder.top)) {
                s = true;
            }
        }

        // if (birdBorder.top > pencilBorder.bottom ||
        //     birdBorder.bottom < pencilBorder.top ||
        //     birdBorder.right < pencilBorder.left ||
        //     birdBorder.left > pencilBorder.right
        // ) {
        //     s = true;
        // }
        // console.log(JSON.stringify(birdBorder) + " " + JSON.stringify(pencilBorder) + " ret:" + s);

        return s;
    }

    check() {
        const bird = this.datastore.get('bird');
        const land = this.datastore.get('land');
        const pencils = this.datastore.get('pencils');

        // console.log("bird.y:" + bird.y + " height:" + bird.height + " land.y:" + land.y);
        if (bird.curY + bird.clippingHeight[0] >= land.y) {
            this.isGameOver = true;
            return;
        }

        const birdsBorder = {
            top: bird.curY,
            bottom: bird.curY + bird.clippingHeight[0],
            left: bird.x,
            right: bird.x + bird.clippingWidth[0]
        };

        const length = pencils.length;
        for (let i = 0; i < length; i++) {
            const pencil = pencils[i];
            const pencilBorder = {
                top: pencil.y,
                bottom: pencil.y + pencil.height,
                left: pencil.x,
                right: pencil.x + pencil.width
            }

            if (Director.isStrike(birdsBorder, pencilBorder)) {
                this.isGameOver = true;
                return;
            }
        }
    }

    run() {
        this.check();

        if (!this.isGameOver) {
            this.distance += this.speed;
            this.datastore.get('background').draw();

            this.queuePencil();
            this.datastore.get('pencils').forEach(function (value, index, array) {
                value.draw();
            });
            this.datastore.get('land').draw();
            this.datastore.get('bird').draw();


            let timer = requestAnimationFrame(() => this.run());
            this.datastore.put('timer', timer);

        } else {
            cancelAnimationFrame(this.datastore.get('timer'));
            this.datastore.ctx.clearRect(0,0,this.datastore.canvas.width,this.datastore.canvas.height);
            this.datastore.get('startButton').draw();
            this.datastore.destroy();
            this.distance = 0;

        }
    }

}